package com.rabbiter.bms.service.impl;

import com.rabbiter.bms.mapper.BookInfoMapper;
import com.rabbiter.bms.mapper.BorrowMapper;
import com.rabbiter.bms.mapper.TscaleMapper;
import com.rabbiter.bms.model.*;
import com.rabbiter.bms.service.TscaleService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import java.util.stream.Collectors;

@Service
public class TscaleServiceImpl implements TscaleService {
    @Resource
    private BookInfoMapper bookInfoMapper;

    @Resource
    private BorrowMapper borrowMapper;

    @Resource
    private TscaleMapper tscaleMapper;

    @Override
    public Integer getCount() {
        return bookInfoMapper.selectCount();
    }

    @Override
    public List<BookInfo> queryBookInfos() {
        return bookInfoMapper.selectAll();
    }

    @Override
    public BookInfo queryBookInfoById(Integer bookid) {
        return bookInfoMapper.selectByPrimaryKey(bookid);
    }

    @Override
    public Integer getSearchCount(Map<String, Object> params) {
        return bookInfoMapper.selectCountBySearch(params);
    }

    @Override
    public List<BookInfo> searchBookInfosByPage(Map<String, Object> params) {
//        System.out.println("Service开始运行");
        List<BookInfo> bookInfos =  bookInfoMapper.selectBySearch(params);
        List<BookInfo> shuffledList = bookInfos.stream().collect(Collectors.toList());
        Collections.shuffle(shuffledList);
//        shuffledList = bookInfos.subList((int)params.get("begin"),(int)params.get("size"));
//        List<BookInfo> resultBookInfos = shuffledList.stream().collect(Collectors.toList());
//        System.out.println("Service运行成功");
        return shuffledList;
    }

    @Override
    public Integer addBookInfo(BookInfo bookInfo) {
        return bookInfoMapper.insertSelective(bookInfo);
    }

    @Override
    public Integer deleteBookInfo(BookInfo bookInfo) {
        int count = 0;
        try{
            Map<String, Object> map = new HashMap<>();
            map.put("bookId", bookInfo.getBookid());
            if(borrowMapper.selectCountBySearch(map) > 0) {
                return -1;
            }
            count = bookInfoMapper.deleteByPrimaryKey(bookInfo.getBookid());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return count;
    }

    @Override
    public Integer deleteBookInfos(List<BookInfo> bookInfos) {
        int count = 0;
        for(BookInfo bookInfo : bookInfos) {
            count += deleteBookInfo(bookInfo);
        }
        return count;
    }

    @Override
    public Integer updateBookInfo(BookInfo bookInfo) {
        return bookInfoMapper.updateByPrimaryKeySelective(bookInfo);
    }

    @Override
    public Integer SearchCount(Map<String, Object> params) {

        return tscaleMapper.selectCountBySearch(params);
    }

    @Override
    public int SearchUploadCount(UploadTable table) {
        return tscaleMapper.selectUploadCount(table);
    }

    @Override
    public List<TScaleTypeTree> searchTScalesByPage(Map<String, Object> params) {
//        System.out.println("Service开始运行");
        List<TScaleDTO> tScales =  tscaleMapper.selectBySearch(params);
//        System.out.println("selectBySearch运行成功");
        List<TScaleTypeTree> tScaleTypeTrees = tscaleMapper.selectTsTree();
//        System.out.println("selectTsTree运行成功");
        for(TScaleDTO tScaleDTO : tScales){
            for(TScaleTypeTree TsTree: tScaleTypeTrees){
                if(TsTree.getChildren() == null){
                    TsTree.setChildren(new ArrayList<>());
                }
                if(tScaleDTO.getProperty().equals(TsTree.getName())){
                    TsTree.getChildren().add(tScaleDTO);
                }
            }
        }
//        for(TScaleTypeTree TsTree: tScaleTypeTrees){
//            System.out.println(TsTree.getName()+":"+TsTree.getChildren().size());
//        }
//        System.out.println(TScales);
//        List<TScaleDTO> shuffledList = TScales.stream().collect(Collectors.toList());
//        Collections.shuffle(shuffledList);
//        shuffledList = bookInfos.subList((int)params.get("begin"),(int)params.get("size"));
//        List<BookInfo> resultBookInfos = shuffledList.stream().collect(Collectors.toList());
//        System.out.println("Service运行成功");
        return tScaleTypeTrees;
    }

    @Override
    public Integer insertUploadTable(UploadTable table) {

        return tscaleMapper.insertUploadTable(table);
    }

    @Override
    public Integer deleteUploadTable(UploadTable table) {
        return tscaleMapper.deleteUploadTable(table);
    }

    @Override
    public Integer insertUploadTable(List<TScaleVO> tScales, int userId) {
        Integer count = 0;
        List<UploadTable> uploadTables = tScales.stream().map(tScale -> new UploadTable(tScale.getId(), (long) userId)).collect(Collectors.toList());
//        System.out.println("重排序");
        List<UploadTable> Test = uploadTables.stream()
                .sorted(Comparator.comparing(UploadTable::getTbId)).collect(Collectors.toList());
//                        .thenComparingInt((UploadTable::getTbId))
//                        .forEach(System.out::println);
        for (UploadTable uploadTable : Test){
            System.out.print(uploadTable.getTbId());
        }
        for (UploadTable uploadTable : uploadTables){
            deleteUploadTable(uploadTable);
            count = insertUploadTable(uploadTable) + count;
        }
        return count;
    }

    @Override
    public Integer deleteUploadTable(List<TScaleVO> tScales, int userId) {
        Integer count = 0;
        List<UploadTable> uploadTables = tScales.stream().map(tScale -> new UploadTable(tScale.getId(), (long) userId)).collect(Collectors.toList());
        for (UploadTable uploadTable : uploadTables){
            count = deleteUploadTable(uploadTable) + count;
        }
        return count;
    }

    @Override
    public int getCountQuestionnaire(AnswerSheet answerSheet) {
        String scaleId =  answerSheet.getScaleId();
        System.out.println("service运行");
//        String csId = answerSheet.getCsId();
//        System.out.println("scaleId"+scaleId);
//        System.out.println(tscaleMapper.getCountQuestionnaire(scaleId));
        return tscaleMapper.getCountQuestionnaire(scaleId);
    }

    @Override
    public List<Questionnaire> selectQuestionnaireByFormId(AnswerSheet answerSheet) {
//        Integer formId =  answerSheet.getFormId();
        return tscaleMapper.selectQuestionnaireByFormId(answerSheet);
    }

    @Override
    public int insertResult(AnswerSheet answerSheet) {
        int count_temp ;
//        int count = 0;
        StringBuilder data = new StringBuilder();
        answerSheet.getParams().entrySet().stream().forEach(entry ->{
            String key = entry.getKey();
            Object value = entry.getValue();
            String uuid = UUID.randomUUID().toString();
            if(!value.toString().isEmpty()){
                if (!data.toString().isEmpty()){
                    data.append(",");
                }
                data.append("(").append(key).append(",").append(value).append(",").append(uuid).append(")");
            }
        });
        System.out.println(data);
        answerSheet.setData(data.toString());
        count_temp = tscaleMapper.insertResult(answerSheet);
        tscaleMapper.deletePreProgram(answerSheet.getCsId());
//        System.out.println(count_temp);
//        if(count_temp != 0){
//            count = tscaleMapper.insertTestScale(answerSheet);
//            tscaleMapper.deleteTempAnswerSheet(answerSheet);
//        }
        return count_temp;
    }

    @Override
    public Map<String,List<AnswerType>> getAnswerType() {
        Map<String,List<AnswerType>> answerTypeMap = new HashMap<>();
        List<AnswerType> answerTypes = tscaleMapper.getAnswerType();
//        int max = 0;
//        for(AnswerType answerType : answerTypes){
//            if (max < answerType.getType()){
//                max = answerType.getType();
//            }
//        }
//        for(int i = 0;i <= max;i++){
//            int finalI = i;
//            List<AnswerType> cahe =  answerTypes.stream().filter(answerType -> answerType.getType() == finalI ).collect(Collectors.toList());
//            answerTypeMap.put(i,cahe);
//        }
//        Class<?> clazz = AnswerType.class;
//        for(int i = 0;i <= max;i++){
//            Method getMethod =
//        }
        for(AnswerType answerType: answerTypes){
            if(answerTypeMap.get(answerType.getType()) == null){
                answerTypeMap.put(answerType.getType(), new ArrayList<>());
                answerTypeMap.get(answerType.getType()).add(answerType);
            }else{
                answerTypeMap.get(answerType.getType()).add(answerType);
            }
        }
        return answerTypeMap;
//        return tscaleMapper.getAnswerType();
    }

    @Override
    public List<Form> getForms(String token) {

        return tscaleMapper.getForms(token);
    }

    @Override
    public Integer getProgramCount(Map<String, Object> params) {
        return tscaleMapper.selectCountProgramBySearch(params);
    }

    @Override
    public List<TProgram> searchProgramByPage(Map<String, Object> params) {
//        List<TProgram> TPrograms =  tscaleMapper.selectProgramBySearch(params);
//        System.out.println(TScales);
//        List<TProgram> shuffledList = TPrograms.stream().collect(Collectors.toList());
//        Collections.shuffle(shuffledList);
//        shuffledList = bookInfos.subList((int)params.get("begin"),(int)params.get("size"));
//        List<BookInfo> resultBookInfos = shuffledList.stream().collect(Collectors.toList());
        List<TProgram> tPrograms = tscaleMapper.selectProgramBySearch(params);
        for (TProgram tProgram : tPrograms){
           String tsp = tProgram.getScaleProgram();
           String [] sps = tsp.split("\\|");
           List<String> ids = new ArrayList<>(Arrays.asList(sps));
           List<TScaleDTO> scalePrograms = tscaleMapper.selectTpByList(ids);
           tProgram.setScalePrograms(scalePrograms);
           if(tProgram.getRyBh() !=null && tscaleMapper.selectRyxxById(tProgram.getRyBh()) != null){
               Ryxx ryxx = tscaleMapper.selectRyxxById(tProgram.getRyBh());
               tProgram.setRyxx(ryxx);
//               System.out.println("获取人员信息："+ ryxx);
           }
            Map<String,Object> tppParam = new HashMap<>();
            tppParam.put("id",tProgram.getId());
            tppParam.put("token",params.get("token"));
        }

//        System.out.println("Service运行成功");
        return tPrograms;
    }

    @Override
    public int insertTProgram(TProgram tProgram) {
        if (tProgram.getId() == null || tProgram.getId().isEmpty()){
            tProgram.setId(String.valueOf(UUID.randomUUID()));
//            System.out.println("tProgram.id = "+tProgram.getId());
        }
        int program =  tscaleMapper.insertTProgram(tProgram);
        Map<String,Object> scale = new HashMap<>();
        scale.put("csBh",tProgram.getCsBh());
        scale.put("csId",tProgram.getId());
        scale.put("id",String.valueOf(UUID.randomUUID()));
//        System.out.println("t_program_scale id = "+scale.get("id"));
//        scale.put("scaleProgram",tProgram.getScaleProgram());
        buildProgramScale(tProgram, scale);
        if (tProgram.getBz() != null){
            scale.put("bz",tProgram.getBz());
        }
        int program_scale = 0;
        if (program == 1) {
//            System.out.println("预案插入成功");
//            System.out.println(scale);
            program_scale = tscaleMapper.insertTProgramScale(scale);
        }
        return program_scale;
    }

    @Override
    public Integer deleteTProgram(TProgram tProgram) {
        return tscaleMapper.deleteTProgram(tProgram.getId());
    }

    @Override
    public Integer deleteTPrograms(List<TProgram> tPrograms) {
        int count = 0;
        for(TProgram tProgram : tPrograms) {
            count += deleteTProgram(tProgram);
        }
        return count;
    }

    @Override
    public Integer updateTProgram(TProgram tProgram) {
       int count =  tscaleMapper.updateTProgram(tProgram);
       if (count != 0){
           Map<String, Object> tProgramScale = new HashMap<>();
           tProgramScale.put("csId",tProgram.getId());
           buildProgramScale(tProgram, tProgramScale);
           tscaleMapper.updateTProgramScale(tProgramScale);
       }
       return count;
    }

    @Override
    public List<Ryxx> getRyxx() {
        return tscaleMapper.getRyxx();
    }

    @Override
    public int insertRyxx(Ryxx ryxx) {
        ryxx.setId(UUID.randomUUID().toString());
        System.out.println("maxBh:"+tscaleMapper.getRyxxMaxBh());
//        String maxBh = tscaleMapper.getRyxxMaxBh();
        String maxBh;
        int newMaxBh;
        if(tscaleMapper.getRyxxMaxBh() == null){
            newMaxBh = 1;
        }else{
            maxBh = tscaleMapper.getRyxxMaxBh();
            newMaxBh = Integer.parseInt(maxBh) + 1;}
        String newMaxBhStr = String.format("%03d",newMaxBh);
        ryxx.setBh(newMaxBhStr);
        return tscaleMapper.insertRyxx(ryxx);
    }

    @Override
    public List<Ryxx> selectRyxx(Map<String,Object> ryxx) {
        System.out.println("ryxx:"+ryxx);
        List<Ryxx> ryxxList =  tscaleMapper.searchRyxxByParam(ryxx);
        for(Ryxx item : ryxxList){
            item.setIsTesting(tscaleMapper.isTesting(item.getId()) >=1);
        }
        return ryxxList;
    }

    @Override
    public Ryxx selectRyxx(String id) {
        return tscaleMapper.selectRyxxById(id);
    }

    @Override
    public int updateRyxx(Ryxx ryxx) {
        return tscaleMapper.updateRyxx(ryxx);
    }

    @Override
    public int insertPreProgram(Map<String, Object> param) {
        tscaleMapper.deletePreProgram((String) param.get("program"));
        return tscaleMapper.insertPreProgram(param);
    }

    @Override
    public List<Map<String, Object>> getItems(String scaleId) {
        return tscaleMapper.getItems(scaleId);
    }

    @Override
    public Map<String, Object> newInsertTProgram(TProgram tProgram) {
        String tProgramId = String.valueOf(UUID.randomUUID());
//        String tProgramScaleId =  String.valueOf(UUID.randomUUID());
        if (tProgram.getId() == null || tProgram.getId().isEmpty()){
            tProgram.setId(tProgramId);
//            System.out.println("tProgram.id = "+tProgram.getId());
        }
        TProgram newTProgram = newBuildProgramScale(tProgram);
        int program =  tscaleMapper.insertTProgram(newTProgram);
//        Map<String,Object> scale = new HashMap<>();
//        scale.put("csBh",tProgram.getCsBh());
//        scale.put("csId",tProgram.getId());
//        scale.put("id",tProgramScaleId);
//        System.out.println("t_program_scale id = "+scale.get("id"));
//        scale.put("scaleProgram",tProgram.getScaleProgram());
        Map<String,Object> result = new HashMap<>();
        result.put("tProgramId",tProgramId);
        result.put("count",program);
        return result;
    }

    @Override
    public int TProgramStatus(Map<String, Object> param) {
        return tscaleMapper.TProgramStatus(param);
    }

    private void buildProgramScale(TProgram tProgram, Map<String, Object> tProgramScale) {
        List<String> bhs = tscaleMapper.getTItemsBh(tProgram.getScaleProgram());
        if(bhs != null){
            Collections.shuffle(bhs);
            StringBuilder itemProgram = new StringBuilder();
            for(String bh : bhs){
                itemProgram.append(bh).append("&");
            }
            itemProgram.deleteCharAt(itemProgram.lastIndexOf("&"));
//            System.out.println(itemProgram);
            tProgramScale.put("itemProgram",itemProgram.toString());
        }
    }
    private TProgram newBuildProgramScale(TProgram tProgram) {
        List<String> bhs = tscaleMapper.getTItemsBh(tProgram.getScaleProgram());
        if(bhs != null){
            Collections.shuffle(bhs);
            StringBuilder itemProgram = new StringBuilder();
            for(String bh : bhs){
                itemProgram.append(bh).append("&");
            }
            itemProgram.deleteCharAt(itemProgram.lastIndexOf("&"));
//            System.out.println(itemProgram);
            tProgram.setItemProgram(itemProgram.toString());
        }
        return tProgram;
    }


}
